home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-11-18 | 13.7 KB | 541 lines | [TEXT/MPS ] |
- {---------------------------------------------------------------------
- #
- # Apple Macintosh Developer Technical Support
- #
- # MultiFinder-Aware Simple TextEdit Sample Application
- #
- # OOPTESample
- #
- # UApplication.inc1.p - Pascal Source
- #
- # Copyright © 1988, 1989 Apple Computer, Inc.
- # All rights reserved.
- #
- # Versions:
- # 1.00 04/89
- # 1.10 02/90
- # 1.11 10/92
- #
- # Components:
- # BuildOOPTESample February 1, 1990
- # MTESample.p February 1, 1990
- # OOPTESample.make February 1, 1990
- # TECommon.h February 1, 1990
- # TESampleGlue.a February 1, 1990
- # TESample.r February 1, 1990
- # TMLRules.make February 1, 1990
- # UApplication.p February 1, 1990
- # UApplication.inc1.p February 1, 1990
- # UDocument.p February 1, 1990
- # UDocument.inc1.p February 1, 1990
- # UTEDocument.p February 1, 1990
- # UTEDocument.inc1.p February 1, 1990
- # UTESample.p February 1, 1990
- # UTESample.inc1.p February 1, 1990
- #
- ---------------------------------------------------------------------}
-
- CONST
- kOSEvent = app4Evt; { Event used by MultiFinder }
- kSuspendResumeMessage = $01; { high byte of suspend/resume event message }
- kClipConvertMask = $02; { bit of message field clip conversion }
- kResumeMask = $01; { bit of message field for resume vs. suspend }
- kMouseMovedMessage = $FA; { high byte of mouse-moved event message }
-
- kErrStrings = 128;
- rUserAlert = 129;
-
- eWrongMachine = 1;
- eSmallSize = 2;
-
-
- (********************************************************************************************)
- (* U t i l i t y r o u t i n e s *)
- (********************************************************************************************)
-
- {This routine is part of the MPW runtime library. This external
- reference to it is done so that we can unload its segment, %A5Init.}
-
- PROCEDURE _DataInit;
- EXTERNAL;
-
- {$S Main}
- {-----------------------------------+
- | AlertUser |
- +-----------------------------------}
- { Display alert, using specified error STR# resource and error code as index }
- PROCEDURE AlertUser(errResID:integer; errCode:integer);
- VAR
- message: Str255;
- dummy: integer;
- BEGIN
- SetCursor(qd.arrow);
- GetIndString(message, errResID, errCode);
- ParamText(message, '', '', '');
- dummy := Alert(rUserAlert, NIL);
- END;
-
- {$S Main}
- {-----------------------------------+
- | BigBadError |
- +-----------------------------------}
- { call AlertUser to display error message, then quit... }
- PROCEDURE BigBadError(errResID:integer; errCode: integer);
- BEGIN
- AlertUser(errResID,errCode);
- ExitToShell;
- END;
-
- {$S Initialize}
- PROCEDURE InitSeg;
- BEGIN
- END;
-
- (********************************************************************************************)
- (* T A p p l i c a t i o n *)
- (********************************************************************************************)
- {$S Initialize}
- {-----------------------------------+
- | IApplication |
- +-----------------------------------}
- PROCEDURE TApplication.IApplication;
-
- VAR
- envRec: sysEnvRec;
- stkNeeded, heapSize: longint;
- dummy: OSErr;
- aDocList: TDocumentList;
-
- BEGIN
- { initialize Mac Toolbox components }
- InitGraf(@qd.thePort);
- InitFonts;
- InitWindows;
- InitMenus;
- TEInit;
- InitDialogs(NIL);
- InitCursor;
-
- { Unload data segment: note that _DataInit must not be in Main! }
- UnloadSeg(@_DataInit);
-
- { Ignore the error returned from SysEnvirons; even if an error occurred, }
- { the SysEnvirons glue will fill in the SysEnvRec }
- dummy := SysEnvirons(curSysEnvVers, envRec);
-
- { Are we running on a 128K ROM machine or better??? }
- IF (envRec.machineType < 0) THEN
- BigBadError(kErrStrings,eWrongMachine); { if not, alert & quit }
-
- { if we need more stack space, get it now }
- stkNeeded := StackNeeded;
- IF (stkNeeded > StackSpace) THEN BEGIN
- { new address is heap size + current stack - needed stack }
- SetApplLimit(Ptr((longint(GetApplLimit) - stkNeeded + StackSpace)));
- END;
-
- { Check for minimum heap size }
- heapSize := longint(GetApplLimit) - longint(ApplicationZone);
- IF (heapSize < HeapNeeded) THEN
- BigBadError(kErrStrings,eSmallSize);
-
- { expand the heap so new code segments load at the top }
- MaxApplZone;
-
- { allocate an empty document list }
- NEW(aDocList);
- fDocList := aDocList;
- fDocList.IDocumentList;
-
- { check to see if WaitNextEvent is implemented }
- fHaveWaitNextEvent := TrapAvailable(_WaitNextEvent, ToolTrap);
-
- { initialize our class variables }
- fCurDoc := NIL;
- fDone := FALSE;
- fInBackground := FALSE;
- fMouseRgn := NIL;
- fWhichWindow := NIL;
- END;
-
- {$S Main}
- {-----------------------------------+
- | EventLoop |
- +-----------------------------------}
- PROCEDURE TApplication.EventLoop;
- VAR
- gotEvent: Boolean;
- anEvent: EventRecord;
- BEGIN
-
- SetUp; { call setup routine }
- DoIdle; { do idle once }
-
- WHILE (fDone = FALSE) DO BEGIN
-
- { always set up fWhichWindow before doing anything }
- fWhichWindow := FrontWindow;
- IF (fWhichWindow <> nil) then begin
- { see if window belongs to a document }
- fCurDoc := fDocList.FindDoc(fWhichWindow);
- { make sure we always draw into correct window }
- SetPort(fWhichWindow);
- END ELSE BEGIN
- fCurDoc := nil;
- END;
-
-
- DoIdle; { call idle time handler }
-
- IF (fHaveWaitNextEvent) THEN BEGIN
- gotEvent := WaitNextEvent(everyEvent, anEvent, SleepVal, fMouseRgn);
- END ELSE BEGIN
- SystemTask;
- gotEvent := GetNextEvent(everyEvent, anEvent);
- END;
- fTheEvent := anEvent;
-
- { make sure we got a real event }
- IF gotEvent THEN BEGIN
- AdjustCursor;
- CASE (fTheEvent.what) OF
- mouseDown : HdlMouseDown;
- mouseUp : HdlMouseUp;
- keyDown,
- autoKey : HdlKeyDown;
- updateEvt : HdlUpdateEvt;
- diskEvt : HdlDiskEvt;
- activateEvt : HdlActivateEvt;
- kOsEvent : HdlOSEvent;
- END; { end switch (fTheEvent.what) }
- END; { if gotEvent }
- AdjustCursor;
- END; {of EventLoop}
- CleanUp;
- END;
-
- {$S Main}
- {-----------------------------------+
- | Setup |
- +-----------------------------------}
- PROCEDURE TApplication.Setup; { Run before event loop starts }
- BEGIN
- END;
-
- {$S Main}
- {-----------------------------------+
- | CleanUp |
- +-----------------------------------}
- PROCEDURE TApplication.CleanUp; { Run at end of loop }
- BEGIN
- UnloadSeg(@InitSeg);
- END;
-
- {$S Main}
- {-----------------------------------+
- | ExitLoop |
- +-----------------------------------}
- PROCEDURE TApplication.ExitLoop; { Call this to exit loop }
- BEGIN
- fDone := TRUE;
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoIdle |
- +-----------------------------------}
- PROCEDURE TApplication.DoIdle; { Idle time handler (blink caret, background tasks) }
- BEGIN
- END;
-
- {$S Main}
- {-----------------------------------+
- | AdjustMenus |
- +-----------------------------------}
- PROCEDURE TApplication.AdjustMenus; { Menu Updater routine }
- BEGIN
- END;
-
- {$S Main}
- {-----------------------------------+
- | HdlOSEvent |
- +-----------------------------------}
- PROCEDURE TApplication.HdlOSEvent; { Calls DoSuspend, DoResume and DoIdle as apropos }
- VAR
- doConvert: Boolean;
- evType: byte;
- BEGIN
-
- { is it a multifinder event? }
- evType := BAnd(BRotR(fTheEvent.message, 24),$00FF);
- CASE evType OF { high byte of message is type of event }
- kMouseMovedMessage :
- DoIdle; { mouse-moved is also an idle event }
- kSuspendResumeMessage : BEGIN
- doConvert := (BAnd(fTheEvent.message, kClipConvertMask) <> 0);
- fInBackground := (BAnd(fTheEvent.message, kResumeMask) = 0);
- IF (fInBackground) THEN
- DoSuspend(doConvert)
- ELSE
- DoResume(doConvert);
- END; { kSuspendResumeMessage }
- END; { CASE Statement }
- END;
-
- {$S Main}
- {-----------------------------------+
- | HdlMouseDown |
- +-----------------------------------}
- PROCEDURE TApplication.HdlMouseDown; { Calls DoContent, DoGrow, DoZoom, etc }
- VAR
- mResult: Longint;
- partCode: integer;
- anEvent: EventRecord;
- aWindow: WindowPtr;
- BEGIN
- partCode := FindWindow(fTheEvent.where, aWindow);
- fWhichWindow := aWindow;
- CASE partCode OF
- inSysWindow : MouseInSysWindow;
- inMenuBar : BEGIN
- AdjustMenus;
- mResult := MenuSelect(fTheEvent.where);
- IF (mResult <> 0) THEN
- DoMenuCommand(HiWord(mResult),LoWord(mResult));
- END;
- inGoAway :
- DoGoAway;
- inDrag :
- DoDrag;
- inGrow :
- IF (fCurDoc <> NIL) THEN BEGIN
- anEvent := fTheEvent;
- fCurDoc.DoGrow(anEvent);
- END;
- inZoomIn,
- inZoomOut :
- IF ((TrackBox(fWhichWindow, fTheEvent.where, partCode)) AND
- (fCurDoc <> NIL)) THEN
- fCurDoc.DoZoom(partCode);
- inContent : { If window is not in front, make it so }
- IF (fWhichWindow <> FrontWindow) THEN
- SelectWindow(fWhichWindow)
- ELSE IF (fCurDoc <> NIL) THEN BEGIN
- anEvent := fTheEvent;
- fCurDoc.DoContent(anEvent);
- END;
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | HdlKeyDown |
- +-----------------------------------}
- PROCEDURE TApplication.HdlKeyDown; { also called for autokey events }
- VAR
- key: char;
- mResult: longint;
- anEvent: EventRecord;
- BEGIN
- key := char(BAnd(fTheEvent.message, charCodeMask));
- IF ((BAnd(fTheEvent.modifiers, cmdKey) <> 0) AND (fTheEvent.what = keyDown)) THEN BEGIN
- { only do command keys if we are not autokeying }
- AdjustMenus; { make sure menus are up to date }
- mResult := MenuKey(key);
- IF (mResult <> 0) THEN BEGIN { if it wasn't a menu key, pass it through }
- DoMenuCommand(HiWord(mResult), LoWord(mResult));
- END;
- END ELSE BEGIN
- IF (fCurDoc <> nil) THEN BEGIN
- anEvent := fTheEvent;
- fCurDoc.DoKeyDown(anEvent);
- END;
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | HdlActivateEvt |
- +-----------------------------------}
- PROCEDURE TApplication.HdlActivateEvt; { handles setup, and calls DoActivate (below) }
- BEGIN
- { event record contains window ptr }
- fWhichWindow := WindowPtr(fTheEvent.message);
-
- { see if window belongs to a document }
- fCurDoc := fDocList.FindDoc(fWhichWindow);
- SetPort(fWhichWindow);
-
- IF (fCurDoc <> NIL) THEN BEGIN
- fCurDoc.DoActivate(BAnd(fTheEvent.modifiers, activeFlag) <> 0);
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | HdlUpdateEvt |
- +-----------------------------------}
- PROCEDURE TApplication.HdlUpdateEvt; { handles setup, and calls DoUpdate (below) }
- BEGIN
- { event record contains window ptr }
- fWhichWindow := WindowPtr(fTheEvent.message);
-
- { see if window belongs to a document }
- fCurDoc := fDocList.FindDoc(fWhichWindow);
- SetPort(fWhichWindow);
-
- IF (fCurDoc <> NIL) THEN BEGIN
- fCurDoc.DoUpdate;
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | HdlMouseUp |
- +-----------------------------------}
- PROCEDURE TApplication.HdlMouseUp;
- BEGIN
- END;
-
- {$S Main}
- {-----------------------------------+
- | HdlDiskEvt |
- +-----------------------------------}
- PROCEDURE TApplication.HdlDiskEvt;
- BEGIN
- END;
-
- {$S Main}
- {-----------------------------------+
- | MouseInSysWindow |
- +-----------------------------------}
- PROCEDURE TApplication.MouseInSysWindow;
- VAR
- anEvent: EventRecord;
- BEGIN
- anEvent := fTheEvent;
- SystemClick(anEvent,fWhichWindow);
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoDrag |
- +-----------------------------------}
- PROCEDURE TApplication.DoDrag;
- BEGIN
- DragWindow(fWhichWindow, fTheEvent.where, qd.screenBits.bounds);
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoGoAway |
- +-----------------------------------}
- PROCEDURE TApplication.DoGoAway;
- VAR
- aWindow: WindowPeek;
- BEGIN
- IF (TrackGoAway(fWhichWindow, fTheEvent.where)) THEN BEGIN
- IF (fCurDoc <> NIL) THEN BEGIN
- fDocList.RemoveDoc(fCurDoc);
- fCurDoc.Free; {TDocument.Free disposes of window}
- END ELSE BEGIN
- aWindow := WindowPeek(fWhichWindow);
- CloseDeskAcc(aWindow^.windowKind);
- END;
-
- { make sure our current document/window references are valid }
- fWhichWindow := FrontWindow;
- IF (fWhichWindow <> NIL) THEN BEGIN
- fCurDoc := fDocList.FindDoc(fWhichWindow);
- SetPort(fWhichWindow);
- END ELSE
- fCurDoc := NIL;
-
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | AdjustCursor |
- +-----------------------------------}
- PROCEDURE TApplication.AdjustCursor; { cursor adjust routine, should setup mouseRgn }
- BEGIN
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoMenuCommand |
- +-----------------------------------}
- PROCEDURE TApplication.DoMenuCommand(menuID,menuItem: integer);
- BEGIN
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoSuspend |
- +-----------------------------------}
- PROCEDURE TApplication.DoSuspend(VAR doClipConvert:Boolean);
- BEGIN
- doClipConvert := FALSE;
- IF (fCurDoc <> NIL) THEN
- fCurDoc.DoActivate(NOT (fInBackground));
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoResume |
- +-----------------------------------}
- PROCEDURE TApplication.DoResume(VAR doClipConvert:Boolean);
- BEGIN
- doClipConvert := FALSE;
- IF (fCurDoc <> NIL) THEN
- fCurDoc.DoActivate(NOT(fInBackground));
- END;
-
- {$S Initialize}
- {-----------------------------------+
- | TrapAvailable |
- +-----------------------------------}
- FUNCTION TApplication.TrapAvailable(tNumber:integer;tType:TrapType):Boolean;
- BEGIN
- { See if the trap exists. On 64K ROM machines, tType will be ignored. }
- TrapAvailable := NGetTrapAddress(tNumber, tType) <>
- NGetTrapAddress(_Unimplemented, ToolTrap);
- END;
-
- {$S Main}
- {-----------------------------------+
- | DocList |
- +-----------------------------------}
- FUNCTION TApplication.DocList:TDocumentList;
- BEGIN
- DocList := fDocList;
- END;
-
- {$S Initialize}
- {-----------------------------------+
- | StackNeeded |
- +-----------------------------------}
- FUNCTION TApplication.StackNeeded: Longint;
- BEGIN
- StackNeeded := 0;
- END;
-
- {$S Initialize}
- {-----------------------------------+
- | HeapNeeded |
- +-----------------------------------}
- FUNCTION TApplication.HeapNeeded: Longint;
- BEGIN
- HeapNeeded := 0;
- END;
-
- {$S Main}
- {-----------------------------------+
- | SleepVal |
- +-----------------------------------}
- FUNCTION TApplication.SleepVal: LongInt;
- BEGIN
- SleepVal := 0;
- END;
-